package com.weijing.pretty_app.util

import java.nio.ByteBuffer

/**
 * 解包
 */
object HexDataParse {
    /**
     * 解析接收到的 Hex 字符串（可能包含多个数据包）
     */
    fun parseHexString(rawHex: String, onParsed: (funcCode: String, data: List<String>) -> Unit) {
        val hexList = rawHex
            .replace(Regex("[^0-9A-Fa-f\\s]"), " ")  // 替换非 hex 字符为空格
            .trim()
            .split(Regex("\\s+"))
            .filter { it.length == 2 }
        var index = 0

        while (index <= hexList.size - 6) { // 至少需要 [AA, FF, 功能码, 长度, 数据, EE]
            if (hexList[index] == KeyUtil.AA && hexList[index + 1] == KeyUtil.FF) {
                val funcCode = hexList[index + 2]
                val lengthHex = hexList[index + 3]
                val length = lengthHex.toInt(16)

                val dataEndIndex = index + 4 + length
                if (dataEndIndex < hexList.size && hexList[dataEndIndex] == KeyUtil.EE) {
                    val data = hexList.subList(index + 4, dataEndIndex)
                    onParsed(funcCode, data)
                    index = dataEndIndex + 1 // 移动到下一个可能的帧头
                } else {
                    // 数据不完整或没有EE，终止循环（等待下次数据补全）
                    break
                }
            } else {
                index++
            }
        }
    }

    /**
     * 把数据字节的十六进制字符串列表，转成无符号长整型数字
     * @param data List<String> 如 ["00","16","E3","60"]
     * @return Long 例如 1500000L
     */
    fun dataToUInt(data: List<String>): Int {
        val cleanData = data.filter { it.uppercase() != KeyUtil.EE }  // 去掉 "EE"
        var result = 0L
        for (byteStr in cleanData) {
            try {
                // 清理不可见字符，防止 "16?"、"?16" 等非法格式
                val cleaned = byteStr.filter { it.isLetterOrDigit() }
                if (cleaned.isNotEmpty()) {
                    val value = cleaned.toInt(16)
                    result = (result shl 8) or value.toLong()
                }
            } catch (e: NumberFormatException) {
                // 忽略非法数据
                e.printStackTrace()
            }
        }
        return result.toInt()
    }

    /**
     * 有符号的字节数据 1字节
     * 如：FB 返回的是 -5
     */
    fun hexByteToSignedInt(hex: String): Int {
        val byteValue = hex.toInt(16)
        return if (byteValue >= 0x80) byteValue - 0x100 else byteValue
    }

    /**
     * 根据字节长度返回不定Int数值 (AA FF E7 03 01 01 8C EE )
     * @param data AA FF [功能码] [长度] [方向] [参数key] [数据. ...] EE
     * 返回的是可变的数据；也就是上方param中方向后面的数值
     */
    fun parseVariableLengthFrame(frame: List<String>): Int? {
        if (frame.size < 6) return null
        if (frame[0].uppercase() != "AA" || frame[1].uppercase() != "FF") return null
        if (frame.last().uppercase() != "EE") return null

        val length = frame[3].toIntOrNull(16) ?: return null
        val dataStartIndex = 4
        val dataEndIndex = dataStartIndex + length
        if (frame.size < dataEndIndex + 1) return null // +1 for EE

        val dataBytes = frame.subList(dataStartIndex, dataEndIndex)
            .map { it.toInt(16).toByte() }
            .toByteArray()

        val value: Long = when (dataBytes.size) {
            1 -> dataBytes[0].toLong()
            2 -> ByteBuffer.wrap(dataBytes).short.toLong()
            4 -> ByteBuffer.wrap(dataBytes).int.toLong()
            else -> dataBytes.fold(0L) { acc, b -> (acc shl 8) or (b.toInt() and 0xFF).toLong() }
        }

        return if (value in Int.MIN_VALUE..Int.MAX_VALUE) value.toInt() else null
    }

    /**
     * Int 数值转 固定4个字节
     */
    fun intToFixed4ByteHex(value: Int): List<String> {
        val byteBuffer = ByteBuffer.allocate(4).putInt(value)
        return byteBuffer.array().map { String.format("%02X", it) }
    }

    /**
     * 如：32 31 31 30 32 33 30 39 30 32
     * @return 2110230902
     */
    fun processNumbers(list:List<String>):String{
        return list.mapNotNull { it.toIntOrNull() } // 转换为Int?，过滤掉非数字
            .map { if (it >= 30) it - 30 else 0 } // 处理每个数字
            .joinToString("") { it.toString() } // 拼接成字符串
    }
}

fun main() {
    val aa = "AA FF D1 0A 32 31 31 30 32 33 30 39 30 32 EE"
    HexDataParse.parseHexString(aa) { funcCode, hexData ->
        val snValue = hexData.mapNotNull { it.toIntOrNull() } // 转换为Int?，过滤掉非数字
            .map { if (it >= 30) it - 30 else 0 } // 处理每个数字
            .joinToString("") { it.toString() }
        println(snValue)
    }
}